package com.bmd.backgroundmanger.service.impl;

import com.bmd.backgroundmanger.entity.ExamPaper;
import com.bmd.backgroundmanger.entity.PaperQuestion;
import com.bmd.backgroundmanger.entity.Question;
import com.bmd.backgroundmanger.mapper.ExamPaperMapper;
import com.bmd.backgroundmanger.mapper.PaperQuestionMapper;
import com.bmd.backgroundmanger.mapper.QuestionMapper;
import com.bmd.backgroundmanger.service.IExamPaperService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 试卷管理 服务实现类
 * </p>
 *
 * @author 刷题App
 * @since 2024-12-19
 */
@Service
public class ExamPaperServiceImpl extends ServiceImpl<ExamPaperMapper, ExamPaper> implements IExamPaperService {

    @Autowired
    private ExamPaperMapper examPaperMapper;

    @Autowired
    private PaperQuestionMapper paperQuestionMapper;

    @Autowired
    private QuestionMapper questionMapper;



    @Override
    public Map<String, Object> getPageData(int page, int size, String title, String status) {
        Map<String, Object> result = new HashMap<>();
        
        LambdaQueryWrapper<ExamPaper> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasLength(title), ExamPaper::getTitle, title)
               .eq(StringUtils.hasLength(status), ExamPaper::getStatus, status)
               .orderByDesc(ExamPaper::getCreateTime);

        Page<ExamPaper> pageObj = new Page<>(page, size);
        Page<ExamPaper> examPaperPage = this.page(pageObj, wrapper);
        
        // 为每个试卷设置题目数量
        for (ExamPaper paper : examPaperPage.getRecords()) {
            Integer questionCount = examPaperMapper.selectQuestionCount(paper.getPaperId());
            paper.setQuestionCount(questionCount != null ? questionCount : 0);
        }

        result.put("papers", examPaperPage.getRecords());
        result.put("total", examPaperPage.getTotal());
        return result;
    }

    @Override
    @Transactional
    public boolean createPaper(ExamPaper examPaper) {
        examPaper.setCreateTime(LocalDateTime.now());
        examPaper.setStatus("draft"); // 默认为草稿状态
        return this.save(examPaper);
    }

    @Override
    @Transactional
    public boolean updatePaper(ExamPaper examPaper) {
        examPaper.setUpdateTime(LocalDateTime.now());
        return this.updateById(examPaper);
    }

    @Override
    public ExamPaper getPaperWithQuestions(Integer paperId) {
        ExamPaper paper = this.getById(paperId);
        if (paper != null) {
            // 获取试卷的题目列表
            List<Question> questions = paperQuestionMapper.selectQuestionsByPaperId(paperId);
            
            // 题目的选项现在直接存储在Question的options字段中（JSON格式）
            // 无需额外查询，MyBatis-Plus会自动反序列化JSON数据
            
            paper.setQuestions(questions);
            paper.setQuestionCount(questions.size());
        }
        return paper;
    }

    @Override
    @Transactional
    public boolean addQuestionToPaper(Integer paperId, Integer questionId, Integer score) {
        // 检查题目是否已存在于试卷中
        LambdaQueryWrapper<PaperQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PaperQuestion::getPaperId, paperId)
               .eq(PaperQuestion::getQuestionId, questionId);
        
        if (paperQuestionMapper.selectCount(wrapper) > 0) {
            return false; // 题目已存在
        }

        // 获取当前试卷中题目的最大顺序号
        Integer maxOrder = paperQuestionMapper.getMaxOrderByPaperId(paperId);
        
        PaperQuestion paperQuestion = new PaperQuestion();
        paperQuestion.setPaperId(paperId);
        paperQuestion.setQuestionId(questionId);
        paperQuestion.setQuestionOrder(maxOrder + 1);
        paperQuestion.setQuestionScore(score != null ? score : 5); // 默认5分
        paperQuestion.setCreateTime(LocalDateTime.now());

        boolean result = paperQuestionMapper.insert(paperQuestion) > 0;
        
        if (result) {
            // 更新试卷总分
            updatePaperTotalScore(paperId);
        }
        
        return result;
    }

    @Override
    @Transactional
    public boolean addQuestionsToPaper(Integer paperId, List<Integer> questionIds) {
        if (questionIds == null || questionIds.isEmpty()) {
            return false;
        }

        List<PaperQuestion> paperQuestions = new ArrayList<>();
        Integer maxOrder = paperQuestionMapper.getMaxOrderByPaperId(paperId);
        
        for (int i = 0; i < questionIds.size(); i++) {
            // 检查题目是否已存在
            LambdaQueryWrapper<PaperQuestion> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PaperQuestion::getPaperId, paperId)
                   .eq(PaperQuestion::getQuestionId, questionIds.get(i));
            
            if (paperQuestionMapper.selectCount(wrapper) == 0) {
                PaperQuestion paperQuestion = new PaperQuestion();
                paperQuestion.setPaperId(paperId);
                paperQuestion.setQuestionId(questionIds.get(i));
                paperQuestion.setQuestionOrder(maxOrder + i + 1);
                paperQuestion.setQuestionScore(5); // 默认5分
                paperQuestion.setCreateTime(LocalDateTime.now());
                paperQuestions.add(paperQuestion);
            }
        }

        boolean result = paperQuestions.isEmpty() || paperQuestionMapper.insertBatch(paperQuestions) > 0;
        
        if (result) {
            // 更新试卷总分
            updatePaperTotalScore(paperId);
        }
        
        return result;
    }

    @Override
    @Transactional
    public boolean removeQuestionFromPaper(Integer paperId, Integer questionId) {
        LambdaQueryWrapper<PaperQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PaperQuestion::getPaperId, paperId)
               .eq(PaperQuestion::getQuestionId, questionId);
        
        boolean result = paperQuestionMapper.delete(wrapper) > 0;
        
        if (result) {
            // 更新试卷总分
            updatePaperTotalScore(paperId);
        }
        
        return result;
    }

    @Override
    @Transactional
    public boolean publishPaper(Integer paperId) {
        ExamPaper paper = this.getById(paperId);
        if (paper != null && "draft".equals(paper.getStatus())) {
            paper.setStatus("published");
            paper.setUpdateTime(LocalDateTime.now());
            return this.updateById(paper);
        }
        return false;
    }

    @Override
    @Transactional
    public boolean archivePaper(Integer paperId) {
        ExamPaper paper = this.getById(paperId);
        if (paper != null) {
            paper.setStatus("archived");
            paper.setUpdateTime(LocalDateTime.now());
            return this.updateById(paper);
        }
        return false;
    }

    @Override
    public List<ExamPaper> getPublishedPapers() {
        return examPaperMapper.selectPublishedPapers();
    }

    @Override
    @Transactional
    public boolean autoComposePaper(Integer paperId, Integer categoryId, String difficultyLevel, Integer questionCount) {
        // 先清空试卷现有题目
        paperQuestionMapper.deleteByPaperId(paperId);
        
        // 构建查询条件
        LambdaQueryWrapper<Question> wrapper = new LambdaQueryWrapper<>();
        if (categoryId != null) {
            wrapper.eq(Question::getCategoryId, categoryId);
        }
        if (StringUtils.hasLength(difficultyLevel)) {
            wrapper.eq(Question::getDifficultyLevel, difficultyLevel);
        }
        wrapper.last("ORDER BY RAND()"); // MySQL随机排序
        
        List<Question> questions = questionMapper.selectList(wrapper);
        
        if (questions.isEmpty()) {
            return false;
        }
        
        // 随机选择题目
        Collections.shuffle(questions);
        int count = Math.min(questionCount != null ? questionCount : 10, questions.size());
        
        List<Integer> selectedQuestionIds = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            selectedQuestionIds.add(questions.get(i).getQuestionId());
        }
        
        return addQuestionsToPaper(paperId, selectedQuestionIds);
    }

    @Override
    @Transactional
    public boolean adjustQuestionOrder(Integer paperId, List<Map<String, Integer>> orderList) {
        for (Map<String, Integer> orderMap : orderList) {
            Integer questionId = orderMap.get("questionId");
            Integer newOrder = orderMap.get("order");
            
            LambdaQueryWrapper<PaperQuestion> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(PaperQuestion::getPaperId, paperId)
                   .eq(PaperQuestion::getQuestionId, questionId);
            
            PaperQuestion paperQuestion = paperQuestionMapper.selectOne(wrapper);
            if (paperQuestion != null) {
                paperQuestion.setQuestionOrder(newOrder);
                paperQuestionMapper.updateById(paperQuestion);
            }
        }
        return true;
    }

    /**
     * 更新试卷总分
     */
    private void updatePaperTotalScore(Integer paperId) {
        LambdaQueryWrapper<PaperQuestion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PaperQuestion::getPaperId, paperId);
        List<PaperQuestion> paperQuestions = paperQuestionMapper.selectList(wrapper);
        
        int totalScore = paperQuestions.stream()
                .mapToInt(PaperQuestion::getQuestionScore)
                .sum();
        
        ExamPaper paper = this.getById(paperId);
        if (paper != null) {
            paper.setTotalScore(totalScore);
            paper.setUpdateTime(LocalDateTime.now());
            this.updateById(paper);
        }
    }
} 